#include "vector3.h"
#include "color.h"
#include <math.h>
#include "Utils.h"

vector3::vector3(void)
{
	this->x = 0.0f;
	this->y = 0.0f;
	this->z = 0.0f;
}
vector3::vector3(const vector3 &a)
{
	this->x = a.x;
	this->y = a.y;
	this->z = a.z;
}
/*
vector3::vector3(const color &colorA)
{
	this->x = colorA.r/255.0f;
	this->y = colorA.g/255.0f;
	this->z = colorA.b/255.0f;
}*/

vector3::vector3(int x, int y, int z)
{
	this->x = (float)(x);
	this->y = (float)(y);
	this->z = (float)(z);
}
vector3::vector3(uint x, uint y, uint z)
{
	this->x = (float)(x);
	this->y = (float)(y);
	this->z = (float)(z);
}
vector3::vector3(float x, float y, float z)
{
	this->x = x;
	this->y = y;
	this->z = z;
}
vector3::~vector3(void)
{
}
float vector3::Dot(const vector3 &b) const
{
	return x*b.x + y*b.y + z*b.z;
}
vector3 vector3::Cross(const vector3 &b) const
{
	return vector3(y*b.z - b.y*z,
		z*b.x - b.z*x, x*b.y - b.x*y);
}
float vector3::Length() const
{
	return sqrt(pow(x,2) + pow(y,2) + pow(z,2));
}
vector3 vector3::Normalize() const
{
	float mag = Length();
	return vector3(x/mag, y/mag , z/mag);
}
vector3 vector3::Negate() const
{
	return vector3(-x, -y, -z);
}
vector3 vector3::operator*(float a) const
{
	return vector3(x * a, y * a, z * a);
}
vector3 vector3::operator/(float a) const
{
	return vector3(x / a, y / a, z / a);
}
vector3 vector3::operator+(const vector3 &b) const
{
	return vector3(x + b.x, y + b.y, z + b.z);
}
vector3 vector3::operator-(const vector3 &b) const
{
	return vector3(x - b.x, y - b.y, z - b.z);
}
vector3 vector3::operator-() const
{
	return vector3(-x, -y, -z);
}
vector3 vector3::Rotate(float fX, float fY, float fZ) const
{
	float rX = x;
	float rY = y;
	float rZ = z;
	float _temp = 0.0f;
	if(fX != 0.0f) {
		_temp = rY * glCos(fX) + rZ * glSin(fX);
		rZ = rY * -glSin(fX) + rZ * glCos(fX);
		rY = _temp;
	} if(fY != 0.0f) {
		_temp = rX * glCos(fY) + rZ * -glSin(fY);
		rZ = rX * glSin(fY) + rZ * glCos(fY);
		rX = _temp;
	} if(fZ != 0.0f) {
		_temp = rX * glCos(fZ) + rY * glSin(fZ);
		rY = rX * -glSin(fZ) + rY * glCos(fZ);
		rX = _temp;
	}

	return vector3(rX, rY, rZ);
}
bool vector3::IsZero() const
{
	if(x != 0.0f)
		return false;
	if(y != 0.0f)
		return false;
	if(z != 0.0f)
		return false;
	return true;
}
vector3 vector3::operator+=(const vector3 &b)
{
	x = x + b.x;
	y = y + b.y;
	z = z + b.z;
	return (*this);
}
vector3 vector3::operator-=(const vector3 &b)
{
	x = x - b.x;
	y = y - b.y;
	z = z - b.z;
	return (*this);
}

vector3 vector3::MoveInDirection(const vector3 &movement, const vector3 &direction) const
{
	vector3 zAxis = direction;
	vector3 xAxis = zAxis.Rotate(0.0f, 90.0f, 0.0f);
	vector3 yAxis = vector3(0.0f, 1.0f, 0.0f);
	xAxis = vector3(xAxis.x, 0.0f, xAxis.z);
	vector3 newPosition = (*this);
	newPosition += (zAxis * movement.z + xAxis * movement.x + yAxis * movement.y);
	return newPosition;
}